package com.thememaker.lockstyle.control;

import com.jfoenix.controls.JFXComboBox;
import com.thememake.common.base.Strings;
import com.thememake.ui.CtsFileChooser;
import com.thememake.ui.Toast;
import com.thememake.ui.colorcontrol.CustomColorDialog;
import com.thememake.ui.dialog.ProgressDialog;
import com.thememake.util.FileUtils;
import com.thememake.util.image.ImageUtils;
import com.thememaker.lockstyle.customview.EditItemHBox;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swing.JFXPanel;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Button;
import javafx.scene.control.*;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.effect.*;
import javafx.scene.image.Image;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Duration;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.TextArea;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

public class FontImageDialog {
//    private static FontImageDialog FontImageDialog;
    private List<CheckBox> checkBoxes;
    private List<String> inputStreamList;
    private String chooseColor="000000ff";
    private String chooseColor2="000000ff";
    private String chooseColor3="000000ff";
    private ObservableList<Object> ttfList;
    private ObservableList<Object> sizeList;
    /*private TextArea allText;*/
    private Text showText,allText;
    private int ttfNumber=0;
    private int sizeNumber=18;
    private boolean wai=false;
    private boolean nei=false;
    private int index = 0;
    private File path;
    private EditItemHBox textFieldheight;
    private EditItemHBox textFieldwidth;
    private String FileName;

//    public static FontImageDialog getInstance() {
//        if (FontImageDialog == null) {
//            FontImageDialog = new FontImageDialog();
//        }
//        return FontImageDialog;
//    }
//

    public VBox getVbox(String text,String type,String w,String h) {
        FileName = type;
        checkBoxes=new ArrayList<>();
        inputStreamList=new ArrayList<>();
        ttfList = FXCollections.observableArrayList();
        try {
            FileUtils.iteratorDirToStream(new File(FileUtils.getResFileOfThemeModel().getParentFile().getPath(), "res" + File.separator + "fonts"), false).filter(file -> file.toString().endsWith(".ttf")||file.toString().endsWith(".TTF")).forEach(file -> {
                ttfList.add(file.toFile().getName().substring(0,file.toFile().getName().length() - 4));
                inputStreamList.add(file.toString());
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        VBox vbox = new VBox();
        vbox.setPrefWidth(900);
        vbox.setPrefHeight(870);
        vbox.setAlignment(Pos.TOP_LEFT);
        vbox.setPadding(new Insets(10, 10, 10, 10));
        addHbox(vbox,text,w,h);
        return vbox;
    }


    private void addHbox(VBox vBox,String text,String w,String h){
        Stage stage = new Stage();
        HBox titleHBox=new HBox();
        HBox titleHBox2=new HBox();
        showText = new Text();
        titleHBox.setAlignment(Pos.TOP_LEFT);
        titleHBox2.setAlignment(Pos.TOP_LEFT);
        HBox ttfHbox=new HBox();
        HBox textHbox=new HBox();
        ttfHbox.setAlignment(Pos.TOP_LEFT);
        Label ttflabel=new Label(" 字体：");
        ttflabel.setId("diy-fontColor");
        JFXComboBox ttfCb = new JFXComboBox();
        ttfHbox.setMargin(ttfCb,new Insets(-5,0,0,0));
        ttfCb.setItems(ttfList);
        ttfCb.getSelectionModel().select(0);
        ttfCb.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                ttfNumber=newValue.intValue();
                updateText(allText,ttfNumber,12,textHbox);
                updateText(showText,ttfNumber,sizeNumber,textHbox);
            }
        });
        ttfHbox.getChildren().addAll(ttflabel,ttfCb);
        Button importButton=new Button(" 导入本地字体 ");
        importButton.setPadding(new Insets(5));
        importButton.setId("diy-button");
        importButton.setOnAction(event -> {
            path = CtsFileChooser.getInstance().showOpenDialog(null, "选择字体所在路径",
                    new FileChooser.ExtensionFilter("TTF", "*.ttf","*.TTF"));
            if(path!=null){
                String name = path.getName().substring(0, path.getName().length() - 4);
                System.out.println(name);
                if (!ttfList.contains(name)) {
                    File toFile=new File(FileUtils.getResFileOfThemeModel().getParentFile().getPath(), "res" + File.separator + "fonts"+File.separator+path.getName());
                    FileUtils.copyFile(path.getPath(),toFile.getPath(),true);
                    ttfList.add(name);
                    inputStreamList.add(toFile.getPath());
                    ttfCb.setItems(ttfList);
                    ttfCb.getSelectionModel().select(ttfList.size()-1);
                    Toast.makeText(stage, "导入成功！", 1000);
                } else {
                    Toast.makeText(stage, "导入失败，字体已存在！", 1000);
                }
            }
        });
        HBox sizeHbox=new HBox();
        sizeHbox.setAlignment(Pos.TOP_LEFT);
        Label sizelabel=new Label("          字号：");
        sizelabel.setId("diy-fontColor");
        JFXComboBox sizeCb = new JFXComboBox();
        sizeHbox.setMargin(sizeCb,new Insets(-5,0,0,0));
       sizeList = FXCollections.observableArrayList();
        sizeList.add("10");
        sizeList.add("11");
        sizeList.add("12");
        sizeList.add("14");
        sizeList.add("16");
        sizeList.add("18");
        sizeList.add("20");
        sizeList.add("22");
        sizeList.add("24");
        sizeList.add("26");
        sizeList.add("28");
        sizeList.add("36");
        sizeList.add("48");
        sizeList.add("56");
        sizeList.add("68");
        sizeList.add("76");
        sizeList.add("88");
        sizeList.add("96");
        sizeList.add("108");
        sizeList.add("116");
        sizeList.add("128");
        sizeList.add("136");
        sizeCb.setItems(sizeList);
        sizeCb.getSelectionModel().select(18);
        sizeCb.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                sizeNumber=newValue.intValue();
                updateText(allText,ttfNumber,12,textHbox);
                updateText(showText,ttfNumber,sizeNumber,textHbox);
            }
        });
        sizeHbox.getChildren().addAll(sizelabel,sizeCb);
        HBox hbox = new HBox();
        hbox.setAlignment(Pos.CENTER_LEFT);
        Label label1 = new Label(" 字体信息： ");
        Label label2 = new Label(" 样式信息： ");
        Label label3 = new Label(" 图片信息： ");
        Label label4 = new Label(" 文字信息： ");
        label1.setStyle("-fx-text-fill: #6E8BA9");
        label2.setStyle("-fx-text-fill: #6E8BA9");
        label3.setStyle("-fx-text-fill: #6E8BA9");
        label4.setStyle("-fx-text-fill: #6E8BA9");
        titleHBox.getChildren().addAll(label1,ttfHbox,importButton,sizeHbox,getPaletteItemView("       字体颜色:",chooseColor,"1",showText,textHbox));
        titleHBox.setMargin(importButton,new Insets(-7,0,0,0));
        titleHBox.setPadding(new Insets(10));
        titleHBox2.getChildren().addAll(label2,createCheckBox("外部阴影",showText,textHbox),getPaletteItemView("外阴影颜色",chooseColor2,"2",showText,textHbox),createCheckBox("内部阴影",showText,textHbox),getPaletteItemView("内阴影颜色",chooseColor3,"3",showText,textHbox),createCheckBox("模糊",showText,textHbox));
        titleHBox2.setPadding(new Insets(0,10,10,10));
        TextField textField = new TextField();
        textField.setPromptText("请输入生成文字");
        textField.setText(text);
        textField.setEditable(true);

        allText = new Text();
        allText.setTextAlignment(TextAlignment.CENTER);
        textField.textProperty().addListener((observable, oldValue, newValue) -> {
            allText.textProperty().setValue(newValue.replace(";",""));
        });
        allText.textProperty().setValue(textField.textProperty().get().replace(";",""));
        HBox textFileHbox=new HBox();
        textFileHbox.setAlignment(Pos.CENTER_LEFT);

         textFieldwidth = EditItemHBox.initEditItem(" 图片宽度", w, 150);
        textFieldwidth.getTextField().textProperty().addListener((observable, oldValue, newValue) -> {
            textHbox.setPrefWidth(Integer.parseInt(textFieldwidth.getEditValue()));
            textHbox.setMaxWidth(Integer.parseInt(textFieldwidth.getEditValue()));
            textHbox.setMaxHeight(Integer.parseInt(textFieldheight.getEditValue()));
            textHbox.setMinWidth(Integer.parseInt(textFieldwidth.getEditValue()));
            textHbox.setMinHeight(Integer.parseInt(textFieldheight.getEditValue()));
            textHbox.setPrefHeight(Integer.parseInt(textFieldheight.getEditValue()));
        });
         textFieldheight =  EditItemHBox.initEditItem(" 图片高度", h, 150);
        textFieldheight.getTextField().textProperty().addListener((observable, oldValue, newValue) -> {
            textHbox.setPrefWidth(Integer.parseInt(textFieldwidth.getEditValue()));
            textHbox.setMaxWidth(Integer.parseInt(textFieldwidth.getEditValue()));
            textHbox.setMaxHeight(Integer.parseInt(textFieldheight.getEditValue()));
            textHbox.setMinWidth(Integer.parseInt(textFieldwidth.getEditValue()));
            textHbox.setMinHeight(Integer.parseInt(textFieldheight.getEditValue()));
            textHbox.setPrefHeight(Integer.parseInt(textFieldheight.getEditValue()));
        });
        EditItemHBox textfiled = EditItemHBox.initEditItem(" 生成文字", text, 150);
        textFileHbox.getChildren().addAll(label3,textFieldwidth,textFieldheight,textfiled);
        textFileHbox.setPadding(new Insets(0,10,10,10));
        vBox.getChildren().addAll(titleHBox,titleHBox2);
        vBox.getChildren().add(textFileHbox);
        vBox.getChildren().add(allText);
        VBox.setMargin(allText,new Insets(15,0,15,50));
        VBox.setMargin(showText,new Insets(0,0,0,50));
        vBox.getStyleClass().addAll("custom-color-dialog");
//        VBox.setMargin(textFileHbox,new Insets(30,0,30,0));
        textHbox.setAlignment(Pos.CENTER);
        textHbox.setPrefWidth(Integer.parseInt(textFieldwidth.getEditValue()));
        textHbox.setMaxWidth(Integer.parseInt(textFieldwidth.getEditValue()));
        textHbox.setMaxHeight(Integer.parseInt(textFieldheight.getEditValue()));
        textHbox.setMinWidth(Integer.parseInt(textFieldwidth.getEditValue()));
        textHbox.setMinHeight(Integer.parseInt(textFieldheight.getEditValue()));
        textHbox.setPrefHeight(Integer.parseInt(textFieldheight.getEditValue()));
        showText.setText(text.split(";")[index]);
        textHbox.getStyleClass().addAll("color-rect", "transparent-pattern");
        VBox.setMargin(textHbox,new Insets(0,0,0,50));
//        allText.getStyleClass().addAll("color-rect", "transparent-pattern");
        textHbox.getChildren().add(showText);
        vBox.getChildren().add(textHbox);
        Button button = new Button("生成");
//        VBox.setMargin(button,new Insets(0,0,0,50));
        button.setFont(Font.font(14));
        button.setPadding(new Insets(0));
        button.setId("diy-button");
        button.setPrefSize(120,30);
        button.setOnAction(event ->{
             path = CtsFileChooser.getInstance().showOpenDirDialog(null, "生成到文件夹...");
            if(path!=null){
                textHbox.setPrefWidth(Integer.parseInt(textFieldwidth.getEditValue()));
                textHbox.setMaxWidth(Integer.parseInt(textFieldwidth.getEditValue()));
                textHbox.setMaxHeight(Integer.parseInt(textFieldheight.getEditValue()));
                textHbox.setMinWidth(Integer.parseInt(textFieldwidth.getEditValue()));
                textHbox.setMinHeight(Integer.parseInt(textFieldheight.getEditValue()));
                textHbox.setPrefHeight(Integer.parseInt(textFieldheight.getEditValue()));
                createTextImage(textField.getText(),showText,textHbox);
            }
        });
        vBox.getChildren().add(button);
        vBox.setMargin(button,new Insets(10,0,0,50));
        updateText(allText,ttfNumber,12,textHbox);
        updateText(showText,ttfNumber,sizeNumber,textHbox);
    }



private void  createTextImage(String text,Text showText,HBox textHbox) {
    Stage stage = new Stage();
    ProgressDialog progressFrom = new ProgressDialog(stage, "正在生成，请稍等……");
    progressFrom.showProgressBar(() -> {
    });
    Platform.runLater(() -> {
        /*String text = allText.getText();*/
        textHbox.getStyleClass().clear();
        snapshot(text,showText,textHbox);
        Timeline timeline = new Timeline();
        timeline.setCycleCount(Timeline.INDEFINITE);
        KeyFrame keyFrame = new KeyFrame(Duration.millis(1000), new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                index++;
                if (index < text.split(";").length) {
                    snapshot(text,showText,textHbox);
                } else {
                    timeline.stop();
                    index = 0;
                    snapshot(text,showText,textHbox);
                    progressFrom.cancelProgressBar();
                    textHbox.getStyleClass().addAll("color-rect", "transparent-pattern");
                    openFile(path);
                }
            }
        });
        timeline.getKeyFrames().add(keyFrame);
        timeline.play();
    });
}


    public void snapshot(String text,Text showText,HBox textHbox) {
        showText.setText(text.split(";")[index]);
        updateText(showText,ttfNumber,sizeNumber,textHbox);
        SnapshotParameters snapshotParameters = new SnapshotParameters();
        snapshotParameters.setFill(Color.TRANSPARENT);
        Image image = textHbox.snapshot(snapshotParameters, null);
        File savePath;
        if(text.split(";")[index].equals(":")||text.split(";")[index].equals("-")||text.split(";")[index].equals("/")){
            savePath = new File(path,FileName+"_dot.png");
        }else if(FileName.equals("week")){
            savePath = new File(path,FileName+"_"+(index+1)+".png");
        }else{
            savePath = new File(path,FileName+"_"+index+".png");
        }
        if (savePath.exists()) {
            savePath.delete();
        }
        savePath.mkdirs();
        try {
            ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", savePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
}
    private void updateText(Text text,int ttfIndex,int sizeIndex,HBox textHbox){
        Font font = null;
        try {
            font = Font.loadFont(new FileInputStream(new File(inputStreamList.get(ttfIndex))), Double.parseDouble((String) sizeList.get(sizeIndex)));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Blend blend2 = new Blend();
        blend2.setMode(BlendMode.MULTIPLY);
        Blend blend1 = new Blend();
        blend1.setMode(BlendMode.MULTIPLY);
        Blend blend = new Blend();
        blend.setMode(BlendMode.MULTIPLY);
        wai=false;
        nei=false;
       for (int i=0;i<checkBoxes.size();i++){
           if(checkBoxes.get(i).isSelected()){
               switch (i){
                   case 0:
                       wai=true;
                       String fontColor = chooseColor2.substring(0, 6);
                       String alphaHex = chooseColor2.substring(6,8);
                       DropShadow ds = new DropShadow();
                       ds.setOffsetY(3.0f);
                       ds.setColor(Color.web(fontColor, ImageUtils.alphaTransform(alphaHex)));
                       blend1.setBottomInput(ds);
                       break;
                   case 1:
                       nei=true;
                       InnerShadow is = new InnerShadow();
                       is.setRadius(1);
                       is.setChoke(0.4);
                       is.setOffsetX(1.0f);
                       is.setOffsetY(1.0f);
                       String fontColor1 = chooseColor3.substring(0, 6);
                       String alphaHex1 = chooseColor3.substring(6,8);
                       System.out.println(fontColor1);
                       is.setColor(Color.web(fontColor1, ImageUtils.alphaTransform(alphaHex1)));
                       blend1.setTopInput(is);
                       break;
                   case 2:
                       GaussianBlur gaussianBlur =new GaussianBlur();
                       blend.setTopInput(gaussianBlur);
                       break;
               }
           }
       }
        blend2.setTopInput(blend);
        blend2.setBottomInput(blend1);
        text.setFont(font);
        String fontColor = chooseColor.substring(0, 6);
        String alphaHex = chooseColor.substring(6,8);
        text.setFill(Color.web(fontColor, ImageUtils.alphaTransform(alphaHex)));
        text.setEffect(blend2);
        textHbox.setPrefWidth(Integer.parseInt(textFieldwidth.getEditValue()));
        textHbox.setMaxWidth(Integer.parseInt(textFieldwidth.getEditValue()));
        textHbox.setMaxHeight(Integer.parseInt(textFieldheight.getEditValue()));
        textHbox.setMinWidth(Integer.parseInt(textFieldwidth.getEditValue()));
        textHbox.setMinHeight(Integer.parseInt(textFieldheight.getEditValue()));
        textHbox.setPrefHeight(Integer.parseInt(textFieldheight.getEditValue()));
    }


    /***
     * 调色板view
     * @return
     */
    private Node getPaletteItemView(String labelText,String chooseColor, String type,Text showText,HBox textHbox) {
        HBox box = new HBox();
        Label label = new Label(labelText == null ? "" : labelText);
        label.setId("diy-fontColor");
        label.setFont(new Font(12));
        box.setAlignment(Pos.CENTER_LEFT);
        Node hBox = getColorPaletteControl(type, (key, color) -> {
                    System.out.println("key： " + key + " color: " + color);
                    handlerColorChanged(type,color,showText,textHbox);
                },chooseColor);
        box.setPadding(new Insets(5, 5, 5, 5));
        box.getChildren().addAll(label, hBox);
        box.setMargin(label,new Insets(-7,3,0,3));
        box.setMargin(hBox,new Insets(-7,25,0,5));
        return box;
    }

    private void handlerColorChanged(String type ,String color,Text showText,HBox textHbox) {
        if(type.equals("1")){
            chooseColor=color;
        }else if(type.equals("2")){
            chooseColor2=color;
        }else {
            chooseColor3=color;
        }
        updateText(allText,ttfNumber,12,textHbox);
        updateText(showText,ttfNumber,sizeNumber,textHbox);
    }


    private Node getColorPaletteControl(String type , BiConsumer<String, String> colorChange, String chooseColor) {
        Stage stage = new Stage();
        Label bgLabel = new Label("█");
        bgLabel.setPrefWidth(10);
        bgLabel.setPrefHeight(10);
        HBox hBox = new HBox();
        hBox.setSpacing(5);
        Button button = new Button("未设置", bgLabel);
        button.setId("diy-button");
        button.setPadding(new Insets(0));
        button.setPrefWidth(90);
        hBox.getChildren().add(button);
        updatePaletteView(chooseColor, button, (Label) button.getGraphic());
        button.addEventHandler(MouseEvent.MOUSE_RELEASED, event -> {
        if(type.equals("2")){
        if(wai){

        }else {
            Toast.makeText(stage, "请选择外部阴影！", 1000);
            return;
        }
        }else if(type.equals("3")) {
            if(nei){

            }else {
                Toast.makeText(stage, "请选择内部阴影！", 1000);
                return;
            }
        }
      if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 1) {
                        String defaultColor;
                        if (chooseColor==null) {
                            defaultColor = "ffffffff";
                        } else {
                            defaultColor = chooseColor;
                        }
                        showCustomColorDialog(defaultColor, button, bgLabel,
                                color -> {
                                    if (colorChange != null){
                                        colorChange.accept("", color);
                                    }
                                });
                    } else if (event.getButton() == MouseButton.SECONDARY ||
                            event.getButton() == MouseButton.MIDDLE) {
                    }
        });
        return hBox;
    }

    private void updatePaletteView(String chooseColor, Button button, Label bgLabel) {
        if (chooseColor != null) {
            chooseColor = chooseColor.replace("#", "");
            button.setText("#" + chooseColor.substring(0, chooseColor.length() - 2));
            button.setTextFill(Color.web(chooseColor));
            bgLabel.setTextFill(Color.web(chooseColor));
        } else {
            button.setText("未设置");
            button.setTextFill(Color.web("#ffffff00"));
            bgLabel.setTextFill(Color.web("#ffffff00"));

        }
    }

    /***
     * 显示颜色选择弹框
     */
    private void showCustomColorDialog(String chooseColor, Button button, Label bgLabel, Consumer<String> colorChange) {
        Stage stage = new Stage();
        CustomColorDialog customColorDialog = new CustomColorDialog(stage);
        customColorDialog.customColorProperty().addListener((ov, t1, t2) -> {
//                chooseColor = customColorDialog.customColorProperty().get().toString().substring(2);//去除0x
//                    updatePaletteView(customColorDialog.customColorProperty().get(), button, bgLabel);
//                    colorPicker.setValue(customColorDialog.customColorProperty().get());
        });
        customColorDialog.setOnSave(() -> handlerUseColor(customColorDialog, button, bgLabel, colorChange));
        customColorDialog.setOnUse(() -> handlerUseColor(customColorDialog, button, bgLabel, colorChange));
        if (Strings.isNullOrEmpty(chooseColor)) {
            chooseColor = "#ffffffff";
        }
        customColorDialog.setCurrentColor(Color.web(chooseColor));
        customColorDialog.show();
    }

    private void handlerUseColor(CustomColorDialog customColorDialog, Button button, Label bgLabel, Consumer<String> colorChange) {
        Color customColor = customColorDialog.customColorProperty().get();
        String customColorStr = customColor.toString().substring(2);//去除0x
        if (colorChange != null) {
            colorChange.accept(customColorStr);
        }
        updatePaletteView(customColorStr, button, bgLabel);
    }


    private  CheckBox createCheckBox(String text,Text showText,HBox textHbox){
        CheckBox checkBox = new CheckBox(text);
        checkBox.setId("diy-fontColor");
        checkBox.setFont(new Font(16));
        checkBoxes.add(checkBox);
        checkBox.setOnAction(event -> {
            updateText(allText,ttfNumber,12,textHbox);
            updateText(showText,ttfNumber,sizeNumber,textHbox);
        });
        HBox.setMargin(checkBox,new Insets(-5,5,0,5));
        return checkBox;
    }

    public void openFile(File file) {
        EventQueue.invokeLater(() -> {
            try {
                Desktop.getDesktop().open(file);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

}